import * as React from 'react';
import Notification from 'rc-notification';
import { Modal, Spin } from 'antd';
export interface ILoadingProps {
  visible?: boolean;
}

import styled from 'styled-components';

const LoadingModal = styled(Modal)`
  .ant-modal-content {
    background-color: transparent !important;
    box-shadow: none !important;
  }
`;
const LoadingSpinner = styled(Spin)`
  width: 100px !important;
  min-height: 50px !important;
  max-height: 50px !important;
  background: none !important;
  -webkit-box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0) !important;
  box-shadow: none !important;
  position: fixed !important;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
`;

export interface ILoading extends React.FC<ILoadingProps> {
  show?: () => void;
  hide?: () => Promise<any>;
  hideAll?: () => void;
}

export const Loading: ILoading = (props: ILoadingProps) => {
  return (
    <LoadingModal
      visible={props.visible === undefined ? true : props.visible}
      footer={null}
      closable={false}
      centered
      zIndex={9999}
    >
      <LoadingSpinner size={'large'} key="loading" delay={500} />
    </LoadingModal>
  );
};

// rc-notification不必要，可以去除，有一定的bug

const notificationInstance = {};

// loading计数
let count = 0;
const defaultDuration = 0; // 模态框不设置关闭时间

/**
 * 挂载loading模态框
 * @param key
 * @param callback
 */
function getNotificationInstance(key: string, callback: (n: any) => void) {
  const cacheKey = key;
  // 检查key对应的实例是否存在，对当前实例进行notice，可以进行更新
  if (notificationInstance[cacheKey]) {
    callback(notificationInstance[cacheKey]);
    return;
  }

  // 不存在时创建一个实例
  Notification.newInstance({}, (notification) => {
    notificationInstance[cacheKey] = notification;
    callback(notification);
  });
}

/**
 * count为0 实例化一个loading模态框，否则加1
 */
function notice() {
  const duration = defaultDuration;
  if (count === 0) {
    // 确保没有实例时再创建实例
    if (Object.getOwnPropertyNames(notificationInstance).length === 0) {
      // 每次创建的实例都是不同的key,防止由于延迟删除后删除错误
      getNotificationInstance(
        `key-${Date.now().toString()}`,
        (notification) => {
          notification.notice({
            content: <Loading visible={true} />,
            duration,
            key: `key-${Date.now().toString()}`,
            closable: true,
          });
        },
      );
    }
  }
  count++;
}

/**
 * 关闭全部loading
 */
function hideAll() {
  // 遍历删除实例,延迟删除，防止太快导致loading闪烁
  Object.keys(notificationInstance).forEach((cacheKey) => {
    setTimeout(() => {
      // eslint-disable-next-line @typescript-eslint/ban-types, no-prototype-builtins
      if ((notificationInstance as Object).hasOwnProperty(cacheKey)) {
        if (Object.getOwnPropertyNames(notificationInstance).length !== 0) {
          notificationInstance[cacheKey].destroy();
          delete notificationInstance[cacheKey];
        }
      }
    });
  });
  count = 0;
}

/**
 * 关闭单个loading
 */
function hide() {
  return new Promise<void>((res) => {
    setTimeout(() => {
      count--;
      if (count <= 0) {
        hideAll();
        res();
      }
    }, 300);
  });
}

Loading.show = notice;
Loading.hide = hide;
Loading.hideAll = hideAll;

export default Loading;
